#include "I2cInitHelper.h"
#include "SimpleCompletion.h"
#include <string.h>

// rtc
I2c_Data_Task_Def i2c1_ctrl;
// eeprom
I2c_Data_Task_Def i2c3_ctrl;

// I2C1 外部RTC数据接收完成中断
void INT_SRC_I2C1_RXI_IrqCallback(void) {

  // 如果是倒数第二位，接收完之后讲发送ACK转为NACK，下一帧到来时就会发送NACK（注意这里其实设置的是下一字节的回复，不是本字节）
  // 只有接收长度2字节起步才能用，如果1字节的接收需要在启动接收时设置NACK。
  if (i2c1_ctrl.receive_data_len >= 2 && i2c1_ctrl.receive_translate_index - i2c1_ctrl.send_translate_index == i2c1_ctrl.receive_data_len - 1) {
    I2C_AckConfig(CM_I2C1, I2C_NACK);
  }

  // 如果是最后一个字节，发送停止条件，停止I2C，同时将结束位转为ACK，方便后续接收（其实下次接收开始前转都行。这里只是方便）
  if (i2c1_ctrl.receive_translate_index - i2c1_ctrl.send_translate_index == i2c1_ctrl.receive_data_len) {
    /* Enable Stop flag interrupt */
    I2C_IntCmd(CM_I2C1, I2C_INT_STOP, ENABLE);
    /* Disable RXI interrupt */
    I2C_IntCmd(CM_I2C1, I2C_INT_RX_FULL, DISABLE);
    /* Generate stop condition */
    I2C_GenerateStop(CM_I2C1);

    I2C_AckConfig(CM_I2C1, I2C_ACK);
    // 如果配置了事件中断，在停止条件事件中通知发送结束
    //completion_done(&(i2c1_ctrl.i2c_sem));
  }

  i2c1_ctrl.data_buf[i2c1_ctrl.receive_translate_index] = I2C_ReadData(CM_I2C1);
  i2c1_ctrl.receive_translate_index++;
}
// I2C1 外部RTC数据接收完成中断

// I2C1 外部RTC数据发送1字节完成中断
void INT_SRC_I2C1_TXI_IrqCallback(void) {
  if (i2c1_ctrl.send_data_len >= i2c1_ctrl.send_translate_index) {// 发送地址完成，未完成的情况。地址需要单独发送
    // 当数据长度+1等于index时，刚好数据发送到末尾（index从0开始）.
    // 但是由于地址位占据了第一位，所以应该刚好相等。发送数据不包含地址位长度。
    I2C_WriteData(CM_I2C1, i2c1_ctrl.data_buf[i2c1_ctrl.send_translate_index]);
    i2c1_ctrl.send_translate_index++;
  } else {// 传送完成
    I2C_IntCmd(CM_I2C1, I2C_INT_TX_EMPTY, DISABLE);
    I2C_IntCmd(CM_I2C1, I2C_INT_TX_CPLT, ENABLE);
    // 如果配置了事件中断，在停止条件事件中通知发送结束
    //completion_done(&(i2c1_ctrl.i2c_sem));
  }
}
// I2C1 外部RTC数据发送1字节完成中断

// 发送停止条件中断
void INT_SRC_I2C1_TEI_IrqCallback(void) {
  // 关闭发送结束中断
  I2C_IntCmd(CM_I2C1, I2C_INT_TX_CPLT, DISABLE);

  // 如果是第一字节，也就是地址字节
  if (i2c1_ctrl.send_translate_index == 0U) {
    // 如果是地址字节，为了这里的判断，因此进来再加对应的地址。
    i2c1_ctrl.send_translate_index++;
    /* Indicate address send finished */
    // 如果属于发送数据
    if (SET == I2C_GetStatus(CM_I2C1, I2C_FLAG_TRA)) {
      /* If Address send receive ACK */
      // 接收到ACK
      if (RESET == I2C_GetStatus(CM_I2C1, I2C_FLAG_NACKF)) {
        /* Config tx buffer empty interrupt function*/
        I2C_IntCmd(CM_I2C1, I2C_INT_TX_EMPTY, ENABLE);
        /* Need transfer first data here */
        I2C_WriteData(CM_I2C1, i2c1_ctrl.data_buf[i2c1_ctrl.send_translate_index]);
        i2c1_ctrl.send_translate_index++;
      } else {// 接收到NACK
        I2C_IntCmd(CM_I2C1, I2C_INT_NACK, DISABLE);
        /* Generate stop if receive NACK */
        I2C_IntCmd(CM_I2C1, I2C_INT_STOP, ENABLE);
        /* Generate stop condition */
        I2C_GenerateStop(CM_I2C1);
      }
    }
  } else {// 如果不是地址字节，关闭中断，停止I2C。这里是主机的操作，因为主机不会被动接收
    /* Data Send finish */

    /* Generate stop condition */
    if (i2c1_ctrl.transport_mode == POST) {
      I2C_IntCmd(CM_I2C1, I2C_INT_STOP, ENABLE);
      I2C_GenerateStop(CM_I2C1);
    } else {
      I2C_GenerateRestart(CM_I2C1);
	  i2c1_ctrl.package_transport_mode = RESPONSE;
      if (i2c1_ctrl.receive_data_len == 1U) {
        I2C_AckConfig(CM_I2C1, I2C_NACK);
      }

      /* Enable RXI interrupt which indicate data receive buffer full */
      // 开启接收满中断。注意这里没开发送中断所以不会进入发送
      I2C_IntCmd(CM_I2C1, I2C_INT_RX_FULL, ENABLE);

      // 发送读地址
      I2C_WriteData(CM_I2C1, (i2c1_ctrl.data_buf[0] << 1U) | I2C_DIR_RX);
    }
  }
}
// 发送停止条件中断

// I2C1 外部RTC事件及错误中断
void INT_SRC_I2C1_EEI_IrqCallback(void) {
  /* If start flag valid */
  // 发送开始信号触发的事件
  if (SET == I2C_GetStatus(CM_I2C1, I2C_FLAG_START)) {
    I2C_ClearStatus(CM_I2C1, I2C_CLR_STARTFCLR | I2C_CLR_NACKFCLR);
    I2C_IntCmd(CM_I2C1, I2C_INT_STOP | I2C_INT_NACK, ENABLE);

    // 是否是发送数据
    if (REQUEST == i2c1_ctrl.package_transport_mode) {
      /* Enable TEI interrupt which indicate address transfer end */
      I2C_IntCmd(CM_I2C1, I2C_INT_TX_CPLT, ENABLE);

      // 发送写地址
      I2C_WriteData(CM_I2C1, (i2c1_ctrl.data_buf[0] << 1U) | I2C_DIR_TX);
      //发送地址需要独立进入一次写完成中断，所以发送需要额外加一个地址，接收不需要。
      // 但是由于需要进行发送完成判断，所以加地址需要写在接收完成
    } else {// 接收模式
      /* if read data length is 1 */
      /* 这里配合接收中断。如果只发送一位，要提前加入NACK设置 */
      if (i2c1_ctrl.receive_data_len == 1U) {
        I2C_AckConfig(CM_I2C1, I2C_NACK);
      }

      /* Enable RXI interrupt which indicate data receive buffer full */
      // 开启接收满中断。注意这里没开发送中断所以不会进入发送
      I2C_IntCmd(CM_I2C1, I2C_INT_RX_FULL, ENABLE);

      // 发送读地址
      I2C_WriteData(CM_I2C1, (i2c1_ctrl.data_buf[0] << 1U) | I2C_DIR_RX);
    }
  }

  // 如果接收到NACK
  /* If NACK interrupt occurred */
  if (SET == I2C_GetStatus(CM_I2C1, I2C_FLAG_NACKF)) {
    /* clear NACK flag*/
    I2C_ClearStatus(CM_I2C1, I2C_CLR_NACKFCLR);
    /* Stop tx or rx process*/
    I2C_IntCmd(CM_I2C1, I2C_INT_TX_EMPTY | I2C_INT_RX_FULL | I2C_INT_TX_CPLT | I2C_INT_NACK, DISABLE);

    /* Generate stop condition */
    I2C_GenerateStop(CM_I2C1);
  }

  // 如果接收到停止消息
  if (SET == I2C_GetStatus(CM_I2C1, I2C_FLAG_STOP)) {
    /* Disable Stop flag interrupt */
    I2C_IntCmd(CM_I2C1, I2C_INT_TX_EMPTY | I2C_INT_RX_FULL | I2C_INT_TX_CPLT | I2C_INT_STOP | I2C_INT_NACK,
               DISABLE);
    I2C_ClearStatus(CM_I2C1, I2C_CLR_STOPFCLR);
    I2C_Cmd(CM_I2C1, DISABLE);

    /* Communication finished */
    // 注意，这里只是完成了一个阶段的发送，并不意味着整个传输都结束了。
    completion_done(&(i2c1_ctrl.i2c_sem));
  }
}
// I2C1 外部RTC事件及错误中断

// I2C3 外部RTC数据接收完成中断
void INT_SRC_I2C3_RXI_IrqCallback(void) {

  // 如果是倒数第二位，接收完之后讲发送ACK转为NACK，下一帧到来时就会发送NACK（注意这里其实设置的是下一字节的回复，不是本字节）
  // 只有接收长度2字节起步才能用，如果1字节的接收需要在启动接收时设置NACK。
  if (i2c3_ctrl.receive_data_len >= 2 && i2c3_ctrl.receive_translate_index - i2c3_ctrl.send_translate_index == i2c3_ctrl.receive_data_len - 1) {
    I2C_AckConfig(CM_I2C3, I2C_NACK);
  }

  // 如果是最后一个字节，发送停止条件，停止I2C，同时将结束位转为ACK，方便后续接收（其实下次接收开始前转都行。这里只是方便）
  if (i2c3_ctrl.receive_translate_index - i2c3_ctrl.send_translate_index == i2c3_ctrl.receive_data_len) {
    /* Enable Stop flag interrupt */
    I2C_IntCmd(CM_I2C3, I2C_INT_STOP, ENABLE);
    /* Disable RXI interrupt */
    I2C_IntCmd(CM_I2C3, I2C_INT_RX_FULL, DISABLE);
    /* Generate stop condition */
    I2C_GenerateStop(CM_I2C3);

    I2C_AckConfig(CM_I2C3, I2C_ACK);
    // 如果配置了事件中断，在停止条件事件中通知发送结束
    //completion_done(&(i2c1_ctrl.i2c_sem));
  }

  i2c3_ctrl.data_buf[i2c3_ctrl.receive_translate_index] = I2C_ReadData(CM_I2C3);
  i2c3_ctrl.receive_translate_index++;
}
// I2C3 外部RTC数据接收完成中断

// I2C3 外部RTC数据发送1字节完成中断
void INT_SRC_I2C3_TXI_IrqCallback(void) {
  if (i2c3_ctrl.send_data_len >= i2c3_ctrl.send_translate_index) {// 发送地址完成，未完成的情况。地址需要单独发送
    // 当数据长度+1等于index时，刚好数据发送到末尾（index从0开始）.
    // 但是由于地址位占据了第一位，所以应该刚好相等。发送数据不包含地址位长度。
    I2C_WriteData(CM_I2C3, i2c3_ctrl.data_buf[i2c3_ctrl.send_translate_index]);
    i2c3_ctrl.send_translate_index++;
  } else {// 传送完成
    I2C_IntCmd(CM_I2C3, I2C_INT_TX_EMPTY, DISABLE);
    I2C_IntCmd(CM_I2C3, I2C_INT_TX_CPLT, ENABLE);
    // 如果配置了事件中断，在停止条件事件中通知发送结束
    //completion_done(&(i2c1_ctrl.i2c_sem));
  }
}
// I2C3 外部RTC数据发送1字节完成中断

// 发送停止条件中断
void INT_SRC_I2C3_TEI_IrqCallback(void) {
  // 关闭发送结束中断
  I2C_IntCmd(CM_I2C3, I2C_INT_TX_CPLT, DISABLE);

  // 如果是第一字节，也就是地址字节
  if (i2c3_ctrl.send_translate_index == 0U) {
    // 如果是地址字节，为了这里的判断，因此进来再加对应的地址。
    i2c3_ctrl.send_translate_index++;
    /* Indicate address send finished */
    // 如果属于发送数据
    if (SET == I2C_GetStatus(CM_I2C3, I2C_FLAG_TRA)) {
      /* If Address send receive ACK */
      // 接收到ACK
      if (RESET == I2C_GetStatus(CM_I2C3, I2C_FLAG_NACKF)) {
        /* Config tx buffer empty interrupt function*/
        I2C_IntCmd(CM_I2C3, I2C_INT_TX_EMPTY, ENABLE);
        /* Need transfer first data here */
        I2C_WriteData(CM_I2C3, i2c3_ctrl.data_buf[i2c3_ctrl.send_translate_index]);
        i2c3_ctrl.send_translate_index++;
      } else {// 接收到NACK
        I2C_IntCmd(CM_I2C3, I2C_INT_NACK, DISABLE);
        /* Generate stop if receive NACK */
        I2C_IntCmd(CM_I2C3, I2C_INT_STOP, ENABLE);
        /* Generate stop condition */
        I2C_GenerateStop(CM_I2C3);
      }
    }
  } else {// 如果不是地址字节，关闭中断，停止I2C。这里是主机的操作，因为主机不会被动接收
    /* Data Send finish */

    /* Generate stop condition */
    if (i2c3_ctrl.transport_mode == POST) {
      I2C_IntCmd(CM_I2C3, I2C_INT_STOP, ENABLE);
      I2C_GenerateStop(CM_I2C3);
    } else {
      I2C_GenerateRestart(CM_I2C3);
	  i2c3_ctrl.package_transport_mode = RESPONSE;
      if (i2c3_ctrl.receive_data_len == 1U) {
        I2C_AckConfig(CM_I2C3, I2C_NACK);
      }

      /* Enable RXI interrupt which indicate data receive buffer full */
      // 开启接收满中断。注意这里没开发送中断所以不会进入发送
      I2C_IntCmd(CM_I2C3, I2C_INT_RX_FULL, ENABLE);

      // 发送读地址
      I2C_WriteData(CM_I2C3, (i2c3_ctrl.data_buf[0] << 1U) | I2C_DIR_RX);
    }
  }
}
// 发送停止条件中断

// I2C3 外部RTC事件及错误中断
void INT_SRC_I2C3_EEI_IrqCallback(void) {
  /* If start flag valid */
  // 发送开始信号触发的事件
  if (SET == I2C_GetStatus(CM_I2C3, I2C_FLAG_START)) {
    I2C_ClearStatus(CM_I2C3, I2C_CLR_STARTFCLR | I2C_CLR_NACKFCLR);
    I2C_IntCmd(CM_I2C3, I2C_INT_STOP | I2C_INT_NACK, ENABLE);

    // 是否是发送数据
    if (REQUEST == i2c3_ctrl.package_transport_mode) {
      /* Enable TEI interrupt which indicate address transfer end */
      I2C_IntCmd(CM_I2C3, I2C_INT_TX_CPLT, ENABLE);

      // 发送写地址
      I2C_WriteData(CM_I2C3, (i2c3_ctrl.data_buf[0] << 1U) | I2C_DIR_TX);
      //发送地址需要独立进入一次写完成中断，所以发送需要额外加一个地址，接收不需要。
      // 但是由于需要进行发送完成判断，所以加地址需要写在接收完成
    } else {// 接收模式
      /* if read data length is 1 */
      /* 这里配合接收中断。如果只发送一位，要提前加入NACK设置 */
      if (i2c3_ctrl.receive_data_len == 1U) {
        I2C_AckConfig(CM_I2C3, I2C_NACK);
      }

      /* Enable RXI interrupt which indicate data receive buffer full */
      // 开启接收满中断。注意这里没开发送中断所以不会进入发送
      I2C_IntCmd(CM_I2C3, I2C_INT_RX_FULL, ENABLE);

      // 发送读地址
      I2C_WriteData(CM_I2C3, (i2c3_ctrl.data_buf[0] << 1U) | I2C_DIR_RX);
    }
  }

  // 如果接收到NACK
  /* If NACK interrupt occurred */
  if (SET == I2C_GetStatus(CM_I2C3, I2C_FLAG_NACKF)) {
    /* clear NACK flag*/
    I2C_ClearStatus(CM_I2C3, I2C_CLR_NACKFCLR);
    /* Stop tx or rx process*/
    I2C_IntCmd(CM_I2C3, I2C_INT_TX_EMPTY | I2C_INT_RX_FULL | I2C_INT_TX_CPLT | I2C_INT_NACK, DISABLE);

    /* Generate stop condition */
    I2C_GenerateStop(CM_I2C3);
  }

  // 如果接收到停止消息
  if (SET == I2C_GetStatus(CM_I2C3, I2C_FLAG_STOP)) {
    /* Disable Stop flag interrupt */
    I2C_IntCmd(CM_I2C3, I2C_INT_TX_EMPTY | I2C_INT_RX_FULL | I2C_INT_TX_CPLT | I2C_INT_STOP | I2C_INT_NACK,
               DISABLE);
    I2C_ClearStatus(CM_I2C3, I2C_CLR_STOPFCLR);
    I2C_Cmd(CM_I2C3, DISABLE);

    /* Communication finished */
    // 注意，这里只是完成了一个阶段的发送，并不意味着整个传输都结束了。
    completion_done(&(i2c3_ctrl.i2c_sem));
  }
}
// I2C3 外部RTC事件及错误中断

//I2Cx Config
void App_I2CxCfg(void) {
  int32_t i32Ret;
  stc_i2c_init_t stcI2cInit;
  float32_t fErr;

  /* Enable I2C1 clock */
  FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_I2C1, ENABLE);
  /************************* Configure I2C1***************************/
  I2C_DeInit(CM_I2C1);

  (void) I2C_StructInit(&stcI2cInit);
  stcI2cInit.u32ClockDiv = I2C_CLK_DIV2;
  stcI2cInit.u32Baudrate = 400000UL;
  stcI2cInit.u32SclTime = 3UL;
  i32Ret = I2C_Init(CM_I2C1, &stcI2cInit, &fErr);
  if (LL_OK != i32Ret) {
    //Initialized failed, add your code here.
  }
  I2C_BusWaitCmd(CM_I2C1, ENABLE);


  /* Enable interrupt function*/
  //I2C_IntCmd(CM_I2C1, I2C_INT_RX_FULL | I2C_INT_TX_EMPTY | I2C_INT_ARBITRATE_FAIL | I2C_INT_GENERAL_CALL, ENABLE);

  /* Enable I2C3 clock */
  FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_I2C3, ENABLE);
  /************************* Configure I2C3***************************/
  I2C_DeInit(CM_I2C3);

  (void) I2C_StructInit(&stcI2cInit);
  stcI2cInit.u32ClockDiv = I2C_CLK_DIV1;
  stcI2cInit.u32Baudrate = 400000UL;
  stcI2cInit.u32SclTime = 0UL;
  i32Ret = I2C_Init(CM_I2C3, &stcI2cInit, &fErr);
  if (LL_OK != i32Ret) {
    //Initialized failed, add your code here.
  }
  I2C_BusWaitCmd(CM_I2C3, ENABLE);


  /* Enable interrupt function*/
  //I2C_IntCmd(CM_I2C3, I2C_INT_RX_FULL | I2C_INT_TX_EMPTY | I2C_INT_ARBITRATE_FAIL | I2C_INT_GENERAL_CALL, ENABLE);
}

/**
 * @brief  发送开始信号，触发开始信号事件
* 这里不处理收发逻辑。不同I2C的启动信号需要独立触发
 * @param  None
 * @retval None
 */
void Master_Start(CM_I2C_TypeDef *CM_I2Cx) {
  /* I2C function command */
  I2C_Cmd(CM_I2Cx, ENABLE);
  /* Config startf and slave address match interrupt function*/
  I2C_IntCmd(CM_I2Cx, I2C_INT_START, ENABLE);

  I2C_SWResetCmd(CM_I2Cx, ENABLE);
  I2C_SWResetCmd(CM_I2Cx, DISABLE);
  /* generate start signal */
  I2C_GenerateStart(CM_I2Cx);
}

/**
 * @brief  主机使用中断发送数据
 * 通用发送函数，需要传入发送信息
 * @retval int32_t:
 *            - LL_OK:           Success
 *            - LL_ERR_BUSY:     Busy
 */
int32_t I2C_Master_Transmit_IT(CM_I2C_TypeDef *CM_I2Cx, I2c_Data_Task_Def *ctrl_obj) {
  int32_t i32Ret = LL_OK;

  // 尝试锁定互斥量。如果1秒内都获取不到，证明I2C1总线忙。如果获取到了就继续执行。
  if (rt_mutex_take(&(ctrl_obj->port_lock), 1000) == RT_EOK) {
    // 这里使用互斥量控制忙碌状态。因此不再需要标志位。
    //stcI2cCom.enComStatus = I2C_COM_BUSY;


    ctrl_obj->package_transport_mode = REQUEST;
    // 请求模式。也就是Master模式，先发送后接收。
    ctrl_obj->send_translate_index = 1;

    //注意，这里发送数据和数据长度应在触发发送数据前就提前设置好。这里不用传入是为了提高效率降低内存,减少缓冲区使用。
    //        stcI2cCom.u32Len = u32Size;
    //        stcI2cCom.pBuf = au8Data;

    /* General start condition */
    Master_Start(CM_I2Cx);
  } else {
    i32Ret = LL_ERR_BUSY;
  }
  SWDT_FeedDog();
  return i32Ret;
}

/**
 * @brief  主机使用中断接收数据
 * 通用接收函数，需要传入发送信息
 * @retval int32_t:
 *            - LL_OK:           Success
 *            - LL_ERR_BUSY:     Busy
 */
int32_t I2C_Master_Receive_IT(CM_I2C_TypeDef *CM_I2Cx, I2c_Data_Task_Def *ctrl_obj) {
  int32_t i32Ret = LL_OK;

  if (rt_mutex_take(&(ctrl_obj->port_lock), 1000) == RT_EOK) {
    // 这里使用通长缓冲区，接收缓冲区直接跟随在发送之后。
    // 一个字节长的地址（暂时不考虑10长度地址。10长度地址的地址第2位是数据位

    ctrl_obj->receive_translate_index = 1 + ctrl_obj->send_translate_index;
    ctrl_obj->package_transport_mode = RESPONSE;

    /* General start condition */
    Master_Start(CM_I2Cx);
  } else {
    i32Ret = LL_ERR_BUSY;
  }
  SWDT_FeedDog();
  return i32Ret;
}

// 一次收发数据
int32_t I2C_Master_Translate_IT(CM_I2C_TypeDef *CM_I2Cx, I2c_Data_Task_Def *ctrl_obj, uint16_t addr) {
	rt_err_t res_flag = RT_EOK;
  // 这里不复用Transmit和reveive，因为锁只有一个。要保证收发流程连贯。

  {// 初始化发送
    completion_done(&(ctrl_obj->i2c_sem));
    //memset(ctrl_obj->data_buf, 0, sizeof(ctrl_obj->data_buf));
    ctrl_obj->package_transport_mode = REQUEST;
    ctrl_obj->data_buf[0] = addr & 0xFF;
    if (ctrl_obj->receive_data_len == 0) {
      ctrl_obj->transport_mode = POST;
    } else {
      ctrl_obj->transport_mode = GET;
    }
  }// 初始化发送

  // 启动发送阶段
  ctrl_obj->package_transport_mode = REQUEST;
  // 这里要计算发送的地址字节
  ctrl_obj->send_translate_index = 0;

  // 是否有接收
  // 启动接收阶段
  if (ctrl_obj->transport_mode == GET) {
    ctrl_obj->receive_translate_index = ctrl_obj->send_data_len + 1;
  }

  /* General start condition */
  Master_Start(CM_I2Cx);
  if (completion_wait(&(ctrl_obj->i2c_sem), 1000) != RT_EOK) {
    rt_kprintf("rtc send error\n");
		res_flag = RT_ETIMEOUT;
  }
  SWDT_FeedDog();

  rt_thread_yield();
  return res_flag;
}

rt_err_t Init_I2c_Ctrl(I2c_Data_Task_Def *ctrl_obj, char *obj_name) {
  memset(ctrl_obj->name, 0, 16);
  strcpy(ctrl_obj->name, obj_name);
  rt_sem_init(&(ctrl_obj->i2c_sem), obj_name, 0, RT_IPC_FLAG_PRIO);
  rt_mutex_init(&(ctrl_obj->port_lock), obj_name, RT_IPC_FLAG_PRIO);
  ctrl_obj->transport_mode = GET;
  ctrl_obj->package_transport_mode = REQUEST;
  ctrl_obj->receive_data_len = 0;
  ctrl_obj->send_data_len = 0;
  ctrl_obj->send_translate_index = 0;
  ctrl_obj->receive_translate_index = 0;
  memset(ctrl_obj->data_buf, 0, 64);
  return RT_EOK;
}
